package com.codeyang.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.codeyang.constant.PhoneConstant;
import com.codeyang.constant.QueueConstant;
import com.codeyang.domain.User;
import com.codeyang.mapper.UserMapper2;
import com.codeyang.model.AliSmsModel;
import com.codeyang.service.UserService;
import com.codeyang.util.LoadUserInfoUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.time.Duration;
import java.util.*;

/**
 * 描述: TO-删除标志-DO
 *
 * @author CodeYang_Site
 * @version 2021/5/27 12:23
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper2, User> implements UserService {

    @Autowired
    private UserMapper2 userMapper2;

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Autowired
    private RabbitTemplate rabbitTemplate;


    /**
     * 更新用户信息
     *
     * @param user
     * @return
     */
    @Override
    public boolean updateById(User user) {
        log.info("更新用户信息{}", "ttt");
        user.setModifyTime(new Date());
        user.setUserLasttime(new Date());
        //DB设计的性别
        user.setSex(user.getSex().equals("1") ? "M" : "F");
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String ip = request.getRemoteAddr();
        user.setUserLastip(ip);
        return super.updateById(user);
    }


    /**
     * 发送短信服务
     * step:
     * 1.获取手机号
     * 2.判断用户是否在5分钟内已经发送了短信 判断redis
     * 3. 没有,就根据字典生产一个验证码,放入redis
     * 4. 组装一个短信对象
     * 5. 放入MQ
     * 短信发送总是有延时的.
     * 让短信服务监听MQ去真实的发送短信
     *
     * @param map
     * @return
     */
    @Override
    public String sendCode(Map<String, String> map) {
        //1.
        String phonenum = map.get("phonenum");
        log.info("发送验证码,手机号为{}", phonenum);
        //2.判断redis

        Set<String> keys = redisTemplate.keys(PhoneConstant.PHONE_CODE_PREFIX + phonenum);
        if (!CollectionUtils.isEmpty(keys) || keys.size() != 0) {
            return "验证码已经发送,请稍后再试";
        }
        //3.生产验证码
        String code = getCode();
        //先存到redis中去 5分钟后失效
        redisTemplate.opsForValue().set(PhoneConstant.PHONE_CODE_PREFIX + phonenum, code, Duration.ofMinutes(5));
        //4.组装短信对象
        AliSmsModel aliSmsModel = new AliSmsModel();
        aliSmsModel.setPhoneNumbers(phonenum);
        // 转换占位符参数 因为阿里短信要求发送 param参数是一个json
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", code);
        String param = jsonObject.toJSONString();
        //设置了
        aliSmsModel.setTemplateParam(param);
        aliSmsModel.setSignName("ego商城");
        aliSmsModel.setTemplateCode("SMS_203185255");
        //获取一下用户id
        String userId = LoadUserInfoUtil.getUserId();
        // 用大的map把数据包装起来
        HashMap<String, Object> data = new HashMap<>(4);
        data.put("userId", userId);
        data.put("aliSmsModel", aliSmsModel);
        // 放mq
        rabbitTemplate.convertAndSend(QueueConstant.PHONE_SEN_EX, QueueConstant.PHONE_SEN_KEY, JSON.toJSONString(data));
        return "验证码发送成功";
    }

    //随机字典
    private static String codeDct = "0123456789";
    //private static String codeDct = "0123456789ABCDEFGHIJKLMNOPQRSTUVWSYZabcdefghijklmnopqrstuvwsyz";

    /**
     * 生成随机数验证码 | 要求只能是数字
     *
     * @return
     */
    private String getCode() {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            int charCode = new Random().nextInt(codeDct.length()) + 1;
            builder.append(codeDct.charAt(charCode));
        }

        return builder.toString();
    }

    /**
     * 保存手机号
     * 1.拿到手机号
     * 2.拿到验证码
     * 3.做校验
     * 4.把验证码从redis删掉
     * 5.更新用户
     *
     * @param userId
     * @param map
     * @return
     */
    @Override
    public String savePhone(String userId, Map<String, String> map) {
        String phonenum = map.get("phonenum");
        String code = map.get("code");
        String realCode = redisTemplate.opsForValue().get(PhoneConstant.PHONE_CODE_PREFIX + phonenum);
        if (StringUtils.isEmpty(realCode)) {
            return "验证码失效了，请重新获取";
        }
        if (!realCode.equals(code)) {
            redisTemplate.delete(PhoneConstant.PHONE_CODE_PREFIX + phonenum);
            return "验证码错误，请重新获取";
        }
        // 成功了
        redisTemplate.delete(PhoneConstant.PHONE_CODE_PREFIX + phonenum);
        User user = userMapper2.selectById(userId);
        user.setUserMobile(phonenum);
        user.setUserLasttime(new Date());
        userMapper2.updateById(user);
        return "绑定手机号成功";
    }
}


